package com.sdkj.fixed.asset.system.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.sdkj.fixed.asset.api.system.out_vo.MenuTreeEntity;
import com.sdkj.fixed.asset.api.system.out_vo.MenuTreeResultEntity;
import com.sdkj.fixed.asset.common.base.BaseMapper;
import com.sdkj.fixed.asset.common.base.BaseService;
import com.sdkj.fixed.asset.common.exception.LogicException;
import com.sdkj.fixed.asset.pojo.system.AuthAction;
import com.sdkj.fixed.asset.pojo.system.RoleAndMenu;
import com.sdkj.fixed.asset.system.mapper.AuthActionMapper;
import com.sdkj.fixed.asset.system.mapper.RoleAndMenuMapper;
import com.sdkj.fixed.asset.system.util.dicUtil.DictParam;
import com.sdkj.fixed.asset.system.util.dicUtil.TranslationDict;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;

/**
 * 菜单管理服务类
 */
@Service
public class AuthActionService extends BaseService<AuthAction> {
    @Autowired
    private AuthActionMapper authActionMapper;
    @Autowired
    private RoleAndMenuMapper roleAndMenuMapper;
    
    @Override
    public BaseMapper getMapper() {
        return authActionMapper;
    }


    /**
     * 新增菜单
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public AuthAction insertMenu(AuthAction entity){
        //校验sourceey
        if(entity.getLevel().equals("1") || entity.getLevel().equals("2")){
            validateSourceKey(entity,"",false);
        }else{
            validateSourceKey(entity,"",true);
        }
        if((!StrUtil.isBlank(entity.getPid())) && StrUtil.isBlank(entity.getTreecode())){
            throw new LogicException("父级结构不能为空");
        }


        if(StrUtil.isBlank(entity.getPid())){
            entity.setPid("NONE");
        }else{
            //判断其父是否初始化可用
            if(authActionMapper.selectByPrimaryKey(entity.getPid()).getIsInitUse() == 2 && entity.getIsInitUse() == 1){
                throw new LogicException("请先将其父节点设为初始化角色可用");
            }

        }
        if(StrUtil.isBlank(entity.getTreecode())){
            entity.setTreecode("");
        }
        entity.setCtime(DateUtil.now());
        entity.setEtime(DateUtil.now());
        entity.setState(1);
        authActionMapper.insertSelective(entity);
        return entity;
    }

    private void validateSourceKey(AuthAction entity,String id,boolean flag) {
        Example example = new Example(AuthAction.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sourceKey",entity.getSourceKey());
        criteria.andEqualTo("state",1);
        if(StrUtil.isNotBlank(id)){
            criteria.andNotEqualTo("id",id);
        }
        if(flag){
            criteria.andCondition(" (level = 1 or level = 2)");
        }
        List<AuthAction> authActions = authActionMapper.selectByExample(example);
        if(authActions.size() > 0){
            throw new LogicException("资源路径已存在");
        }
    }

    /**
     * 修改菜单
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public AuthAction editMenu(AuthAction entity){
        AuthAction authAction = authActionMapper.selectByPrimaryKey(entity.getId());
        if(authAction == null || authAction.getState() == 2){
            throw new LogicException("菜单不存在");
        }
        //校验sourceey
        if(entity.getLevel().equals("1") || entity.getLevel().equals("2")){
            validateSourceKey(entity,entity.getId(),false);
        }else{
            validateSourceKey(entity,entity.getId(),true);
        }
        if((!StrUtil.isBlank(entity.getPid())) && StrUtil.isBlank(entity.getTreecode())){
            throw new LogicException("父级结构不能为空");
        }
        if(StrUtil.isBlank(entity.getPid())){
            entity.setPid("NONE");
        }else{
            //判断其父是否初始化可用
            if(authActionMapper.selectByPrimaryKey(entity.getPid()).getIsInitUse() == 2 && entity.getIsInitUse() == 1){
                throw new LogicException("请先将其父节点设为初始化角色可用");
            }
            //菜单下是否有子菜单
            Example example = new Example(AuthAction.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andLike("treecode",entity.getId()+"%");
            criteria.andEqualTo("state",1);
            criteria.andEqualTo("isInitUse",1);
            if (authActionMapper.selectByExample(example).size() > 0 && entity.getIsInitUse() == 2) {
                throw new LogicException("请先将其子节点设为初始化角色不可用");
            }
        }
        if(StrUtil.isBlank(entity.getTreecode())){
            entity.setTreecode("");
        }
        if(!entity.getPid().equals(authAction.getPid())){
            throw new LogicException("不能修改父级");
        }
        authAction.setEtime(DateUtil.now());
        authAction.setEuser(entity.getEuser());
        authAction.setComments(entity.getComments());
        authAction.setIcon(entity.getIcon());
        authAction.setIsEndMenu(entity.getIsEndMenu());
        authAction.setIsInitUse(entity.getIsInitUse());
        authAction.setLevel(entity.getLevel());
        authAction.setName(entity.getName());
        authAction.setSort(entity.getSort());
        authAction.setSourceKey(entity.getSourceKey());
        authAction.setUrl(entity.getUrl());
        authAction.setType(entity.getType());
        authActionMapper.updateByPrimaryKeySelective(authAction);
        return entity;
    }
    /**
     * 删除菜单
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteMenu(AuthAction entity){
        AuthAction authAction = authActionMapper.selectByPrimaryKey(entity.getId());
        if(authAction == null || authAction.getState() == 2){
            throw  new LogicException("菜单不存在");
        }
        //查询是否与角色绑定
        Example example = new Example(RoleAndMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("authId",entity.getId());
        List<RoleAndMenu> roleAndMenus = roleAndMenuMapper.selectByExample(example);
        if(roleAndMenus.size() > 0){
            throw  new LogicException("有角色引用菜单，不可以删除");
        }
        //查询是否有子菜单
        Example example2 = new Example(AuthAction.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("pid",authAction.getId());
        List<AuthAction> parks = authActionMapper.selectByExample(example2);
        if(parks.size() > 0){
            throw  new LogicException("菜单存在子节点,不可以删除");
        }
        entity.setState(2);
        entity.setEtime(DateUtil.now());
        authActionMapper.updateByPrimaryKeySelective(entity);
    }
    /**
     * 获取菜单树
     * @return
     */
    @TranslationDict({@DictParam(dictValueFiled = "level",dictNameFiled = "level",dictCode = "SYS_MENU_LEVEL")})
    public List<MenuTreeEntity> getMenuTrees(String name){
        List<MenuTreeResultEntity> menuTree = authActionMapper.getMenuTree(name);
        //查询所有根节点
        Example example = new Example(AuthAction.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("pid","NONE");
        criteria.andEqualTo("state",1);
        if(StrUtil.isNotBlank(name)){
            criteria.andLike("name","%"+name+"%");
        }
        example.setOrderByClause("sort*1");
        List<AuthAction> authActions = authActionMapper.selectByExample(example);

        //组树
        List<MenuTreeEntity> menuTrees = new ArrayList<MenuTreeEntity>();
        for(AuthAction authAction : authActions){
            MenuTreeEntity menuTreeEntity = new MenuTreeEntity();
            menuTreeEntity.setLabel(authAction.getName());
            menuTreeEntity.setLevel(authAction.getLevel().toString());
            menuTreeEntity.setParentId(authAction.getPid());
            menuTreeEntity.setSourceKey(authAction.getSourceKey());
            menuTreeEntity.setValue(authAction.getId());
            menuTreeEntity.setAuthId(authAction.getId());
            menuTreeEntity.setChildren(findChildren(menuTree,authAction.getId()));
            menuTrees.add(menuTreeEntity);
        }

        return menuTrees;
    }
    private List<MenuTreeEntity> findChildren(List<MenuTreeResultEntity> menuTree,String pid){
        List<MenuTreeEntity> menuTreeEntityList = new ArrayList<>();
        for (MenuTreeResultEntity menu : menuTree) {
            MenuTreeEntity menuTreeEntity = new MenuTreeEntity();
            if(menu.getParentId().equals(pid)){
                menuTreeEntity.setLabel(menu.getName());
                menuTreeEntity.setLevel(menu.getLevel());
                menuTreeEntity.setParentId(menu.getParentId());
                menuTreeEntity.setSourceKey(menu.getSourceKey());
                menuTreeEntity.setValue(menu.getAuthId());
                menuTreeEntity.setAuthId(menu.getAuthId());
                List<MenuTreeEntity> children = findChildren(menuTree, menu.getAuthId());
                if(children.size() > 0){
                    menuTreeEntity.setChildren(children);
                }
                menuTreeEntityList.add(menuTreeEntity);
            }
        }
        return menuTreeEntityList;
    }
}
